package com.itheima.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.article.pojo.ApAuthor;
import com.itheima.article.feign.AuthorFegin;
import com.itheima.common.constants.BusinessConstants;
import com.itheima.common.enums.HttpCodeEnum;
import com.itheima.common.exception.LeadNewsException;
import com.itheima.common.vo.PageResultVo;
import com.itheima.common.vo.ResultVo;
import com.itheima.user.dto.ApUserRealnamePageRequestDto;
import com.itheima.user.mapper.ApUserMapper;
import com.itheima.user.mapper.ApUserRealnameMapper;
import com.itheima.user.pojo.ApUser;
import com.itheima.user.pojo.ApUserRealname;
import com.itheima.user.service.ApUserRealnameService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.wemedia.pojo.WmUser;
import com.itheima.wemedia.feign.WmUserFeign;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Map;

/**
 * @description <p>APP实名认证信息 业务实现</p>
 *
 * @version 1.0
 * @package com.itheima.user.service.impl
 */
@Service
@Slf4j
public class ApUserRealnameServiceImpl extends ServiceImpl<ApUserRealnameMapper, ApUserRealname> implements ApUserRealnameService {

    @Autowired
    private ApUserMapper apUserMapper;
    @Autowired
    private WmUserFeign wmUserFeign;
    @Autowired
    private AuthorFegin authorFegin;
    @Override
    public PageResultVo<ApUserRealname> findPage(ApUserRealnamePageRequestDto dto) {
        IPage<ApUserRealname> page = new Page<>(dto.getPage(),dto.getSize());
        LambdaQueryWrapper<ApUserRealname> lqw = new LambdaQueryWrapper();
//        LambdaQueryWrapper<ApUserRealname> queryWrapper = Wrappers.<ApUserRealname>lambdaQuery();
        lqw.eq(dto.getStatus()!=null,ApUserRealname::getStatus,dto.getStatus());
        page = page(page,lqw);
        return PageResultVo.pageResult(page.getCurrent(),page.getSize(),page.getTotal(),page.getRecords());
    }

    @Override
    public void authFail(Map<String, Object> map) {
        Integer id = (Integer)map.get("id");
        String reason = (String)map.get("msg");
        //非空校验
        if (id==null || StringUtils.isEmpty(reason)){
            throw new LeadNewsException(HttpCodeEnum.PARAM_REQUIRE);
        }
        //构建对象
        ApUserRealname apUserRealname = new ApUserRealname();
        apUserRealname.setId(id);
        apUserRealname.setReason(reason);
        apUserRealname.setUpdatedTime(LocalDateTime.now());
        apUserRealname.setStatus(BusinessConstants.ApUserRealnameConstants.AUTH_REJECT);

        //更新
        updateById(apUserRealname);
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    @GlobalTransactional
    public void authPass(Map<String, Object> map) {
        //审核通过，需要将状态修改为9，然后远程调用创建自媒体服务
        Integer id = (Integer)map.get("id");
        String reason = (String)map.get("msg");
        //非空校验
        if (id==null || StringUtils.isNotEmpty(reason)){
            throw new LeadNewsException(HttpCodeEnum.PARAM_REQUIRE);
        }
        log.debug("通过请求来了......");
        //更新字段
        ApUserRealname pojo = new ApUserRealname();
        pojo.setId(id);
        pojo.setUpdatedTime(LocalDateTime.now());
        pojo.setStatus(BusinessConstants.ApUserRealnameConstants.AUTH_PASS);
        updateById(pojo);
        log.debug("实名认证更新认证状态：id={}", id);

        //3. 更新用户信息，认证通过、flag为自媒体人
        // 前端传来的id不是用户的id, 通过查询实名认证信息，得到真正的用户id
        ApUserRealname userRealname = getById(id); // -100
        if(null == userRealname){
            throw new LeadNewsException(HttpCodeEnum.DATA_NOT_EXIST);
        }
        Integer appUserId = userRealname.getUserId();
        // 更新用户信息
        ApUser apUser = new ApUser();
        apUser.setId(appUserId);//根据id修改用户信息
        // 修改为认证通过
        apUser.setIsIdentityAuthentication(BusinessConstants.ApUserConstants.AUTHENTICATED);
        // 从普通用户升级为自媒体人
        apUser.setFlag(BusinessConstants.ApUserConstants.FLAG_WEMEDIA);
        apUserMapper.updateById(apUser);
        apUser = apUserMapper.selectById(appUserId);
        log.debug("实名认证 从普通用户升级为自媒体人：id={}, appUserId={}", id, appUserId);
//        实现自媒体的远程调用
        Integer wmUserId = addWmUser(appUserId, apUser);
        log.debug("实名认证 添加自媒体账号成功：id={}, appUserId={}, wmUserId={}", id, appUserId,wmUserId);
        addApAuthor(wmUserId, apUser);
        log.debug("实名认证 添加作者账号成功：id={}, appUserId={}, wmUserId={}", id, appUserId,wmUserId);
        //6. 事务控制


    }
    private Integer addWmUser(Integer appUserId,ApUser appUserInfo) {//返回自媒体id,添加作者信息时使用
        //这里远程调用自媒体微服务有什么用
        //根据用户id去查询wm_User表，如果没有则创建,远程调用查询
        ResultVo<WmUser> wmUserResult = wmUserFeign.getByAppUserId(appUserId);
        if (!wmUserResult.isSuccess()) {
            throw new LeadNewsException("调用自媒体微服务失败");
        }
        WmUser wmUser = wmUserResult.getData();
        if (wmUser==null){
            wmUser = new WmUser();
            BeanUtils.copyProperties(appUserInfo, wmUser);
            wmUser.setId(null);
            wmUser.setApUserId(appUserId);
            wmUser.setNickname(appUserInfo.getName());
            wmUser.setType(BusinessConstants.WmUserConstants.TYPE_PERSONAL);
            wmUser.setStatus(BusinessConstants.WmUserConstants.STATUS_OK);
            wmUser.setCreatedTime(LocalDateTime.now());
            //
            log.debug("准备添加自媒体");
            ResultVo<WmUser> insertResult = wmUserFeign.add(wmUser);
            if (!insertResult.isSuccess()) {
                // 添加自媒体失败了
                throw new LeadNewsException("调用自媒体微服务添加账号失败");
            }
            wmUser = insertResult.getData();
            log.debug("自媒体已创建");
        }
        log.debug("自媒体已存在");
         return wmUser.getId();
    }
    /**
     * 添加作者信息
     * @param wmUserId
     * @param appUserInfo
     */
    private void addApAuthor(Integer wmUserId, ApUser appUserInfo) {
        //1. 查询作者是否存在
        //1.1 远程调用文章微服务查询
        ResultVo<ApAuthor> getResult = authorFegin.getByApUserIdWmUserId(appUserInfo.getId(), wmUserId);
        //1.2 查询结果isSuccess不为true，失败要报错
        if(!getResult.isSuccess()){
            throw new LeadNewsException("调用文章微服务 查询作者信息失败");
        }
        //1.3 获取返回的数据
        ApAuthor author = getResult.getData();
        //2. 不存在则添加作者信息
        if(null == author) {
            //2.1 构建作者pojo对象
            author = new ApAuthor();
            //2.2 pojo设置属性值
            author.setName(appUserInfo.getName());
            author.setType(BusinessConstants.ApAuthorConstants.A_MEDIA_USER);
            author.setUserId(appUserInfo.getId());
            author.setWmUserId(wmUserId);
            author.setCreatedTime(LocalDateTime.now());
            //2.3 远程调用添加
            ResultVo addResult = authorFegin.add(author);
            //2.4 对添加结果判断，如果失败则报错
            if(!addResult.isSuccess()){
                throw new LeadNewsException("调用文章微服务 添加作者信息失败");
            }
        }
        //java.sql.SQLIntegrityConstraintViolationException: Duplicate entry '2-lisi' for key 'idx_type_name'
        log.debug("用户已存在");
    }




}
